﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.IO;
using System.Threading;
using System.Diagnostics;

namespace NewSeasonFinder
{
    public partial class Form_Main : Form
    {

        private ContextMenuStrip rightMouseButtonMenu;
        private System.Threading.AutoResetEvent ThreadObj = new System.Threading.AutoResetEvent(false);
        private XmlDocument xmldoc_Folders;
        private XmlDocument xmldoc_Shows;
        private XmlDocument xmldoc_SubList;
        private string share_folder = "";
        private CopyOrMoveFile copy_or_move_file = null;

        private const string STR_RefreshList = "刷新整个列表";
        private const string STR_RefreshPart = "刷新所选部分";
        private const string STR_RefreshSrt = "刷新字幕";
        private const string STR_SearchUndownloadsForOneShow = "查找本季未下载集数";
        private const string STR_SearchUndownloadsForAllShow = "查找所有未下载集数";
        private const string STR_Mark = "标记";
        private const string STR_Unmark = "移除标记";
        private const string STR_Playback = "播放";
        private const string STR_RenameVideoFile = "重命名文件";
        private const string STR_RenameVideoFile_Auto = "自動重命名文件";
        private const string STR_SearchSubtitles = "查找本集字幕";
        private const string STR_RenameSubtitles = "重命名字幕文件";
        private const string STR_MoveSubFile = "移动字幕到视频文件夹";
        private const string STR_FileDetails = "文件信息";
        private const string STR_OpenFolder = "打开文件夹";
        private const string STR_VideoMoveTo = "移动到...";
        private const string STR_VideoMoveToAndShare = "移动并保留共享...";
        private const string STR_VideoCopyTo = "复制到...";

        private string[] Extensions_Video = { "avi", "rmvb", "mkv" };
        private string[] Extensions_Srt = { "srt", "ass" };
        private char[] splitChar = { '.', ' ', '[', ']' };

        private const string STR_SearchSite = "http://shooter.cn/search/";

        public Form_Main()
        {
            InitializeComponent();
            progressBar1.Visible = false;
            this.Text = "追美剧 " + Application.ProductVersion;
            xmldoc_SubList = new XmlDocument();
            RefreshTreeView();
        }

        #region Menu

        /// <summary>
        /// 文件夹选择菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 目标文件夹ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FolderManage form_FolderSelect = new FolderManage();
            if (form_FolderSelect.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                RefreshTreeView();
            }
        }

        /// <summary>
        /// 剧集添加删除菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 剧集ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowManage form_ShowManage = new ShowManage();
            if (form_ShowManage.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                RefreshTreeView();
            }
        }

        /// <summary>
        /// 说明菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 说明ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form_About formAbout = new Form_About();
            formAbout.ShowDialog();
        }

        #endregion Menu

        #region Buttons

        /// <summary>
        /// 刷新列表按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_Refresh_Click(object sender, EventArgs e)
        {
            RefreshTreeView();
        }
        
        /// <summary>
        /// 右键点击列表项,选择所点列表项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            treeView1.SelectedNode = e.Node;
        }

        //在点击前清楚选择项
        private void treeView1_MouseDown(object sender, MouseEventArgs e)
        {
            treeView1.SelectedNode = null;
        }


        /// <summary>
        /// 双击ListBox,复制其中字符串用于查询
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (listBox1.SelectedIndex >= 0)
            {
                Clipboard.SetDataObject(listBox1.SelectedItem.ToString());
            }
        }

        private void ResetBrowserButton_Click(object sender, EventArgs e)
        {
            BrowserReset();
        }

        #endregion Buttons

        #region RightClick

        /// <summary>
        /// 右键点击，显示菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                rightMouseButtonMenu = new ContextMenuStrip();
                if (treeView1.SelectedNode != null)
                {
                    if (treeView1.SelectedNode.Level == 0)
                    {
                        //所选为剧集
                        rightMouseButtonMenu.Items.Add(STR_RefreshPart);
                        rightMouseButtonMenu.Items.Add(STR_RefreshList);
                    }
                    else if (treeView1.SelectedNode.Level == 1)
                    {
                        //所选为季
                        rightMouseButtonMenu.Items.Add(STR_SearchUndownloadsForOneShow);
                        rightMouseButtonMenu.Items.Add("-");
                        {   //视频文件移动并保留共享
                            if (Directory.Exists(share_folder))
                            {
                                rightMouseButtonMenu.Items.Add(CreateFolderSelectMenu(2));
                            }
                        }
                        {   //视频文件移动到
                            rightMouseButtonMenu.Items.Add(CreateFolderSelectMenu(0));
                        }
                        //{   //视频文件复制到
                        //    rightMouseButtonMenu.Items.Add(CreateFolderSelectMenu(1));
                        //}
                        rightMouseButtonMenu.Items.Add("-");
                        rightMouseButtonMenu.Items.Add(STR_RefreshPart);
                        rightMouseButtonMenu.Items.Add(STR_RefreshList);
                    }
                    else if (treeView1.SelectedNode.Level == 2)
                    {
                        //所选为视频文件
                        rightMouseButtonMenu.Items.Add(STR_SearchSubtitles);    //查找字幕
                        rightMouseButtonMenu.Items.Add(STR_RefreshSrt);         //刷新字幕
                        rightMouseButtonMenu.Items.Add(STR_RenameVideoFile);    //重命名视频
                        rightMouseButtonMenu.Items.Add(STR_RenameVideoFile_Auto);   //自動重命名
                        rightMouseButtonMenu.Items.Add(STR_MoveSubFile);        //移动字幕
                        rightMouseButtonMenu.Items.Add("-");                    //-----
                        if (treeView1.SelectedNode.ForeColor == Color.Black)
                        { 
                            rightMouseButtonMenu.Items.Add(STR_Mark);           //标记
                        }
                        else 
                        {
                            rightMouseButtonMenu.Items.Add(STR_Unmark);         //去除标记
                        }
                        rightMouseButtonMenu.Items.Add("-");                    //-----
                        rightMouseButtonMenu.Items.Add(STR_Playback);           //播放
                        rightMouseButtonMenu.Items.Add("-");                    //-----
                        if (Directory.Exists(share_folder))                     //视频文件移动并保留共享
                        {
                            rightMouseButtonMenu.Items.Add(CreateFolderSelectMenu(2));
                        }
                        rightMouseButtonMenu.Items.Add(CreateFolderSelectMenu(0));  //视频文件移动到
                        //{   //视频文件复制到
                        //    rightMouseButtonMenu.Items.Add(CreateFolderSelectMenu(1));
                        //}
                        rightMouseButtonMenu.Items.Add("-");                    //-----
                        rightMouseButtonMenu.Items.Add(STR_FileDetails);        //文件信息
                        rightMouseButtonMenu.Items.Add(STR_OpenFolder);         //打开文件夹
                        rightMouseButtonMenu.Items.Add("-");                    //-----
                        rightMouseButtonMenu.Items.Add(STR_RefreshList);        //刷新
                    }
                    else if (treeView1.SelectedNode.Level == 3)
                    {
                        //所选为字幕文件
                        rightMouseButtonMenu.Items.Add(STR_RenameSubtitles);
                        rightMouseButtonMenu.Items.Add(STR_MoveSubFile);
                        rightMouseButtonMenu.Items.Add("-");
                        rightMouseButtonMenu.Items.Add(STR_FileDetails);
                        rightMouseButtonMenu.Items.Add(STR_OpenFolder);
                        rightMouseButtonMenu.Items.Add("-");
                        rightMouseButtonMenu.Items.Add(STR_RefreshList);
                    }

                    rightMouseButtonMenu.ItemClicked += new ToolStripItemClickedEventHandler(this.rightMouseButtonMenu_Click);
                    rightMouseButtonMenu.Show(MousePosition);
                }
                else
                {
                    rightMouseButtonMenu.Items.Add(STR_RefreshList);
                    rightMouseButtonMenu.ItemClicked += new ToolStripItemClickedEventHandler(this.rightMouseButtonMenu_Click);
                    rightMouseButtonMenu.Show(MousePosition);
                }
            }
        }

        /// <summary>
        /// 右键菜单功能处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void rightMouseButtonMenu_Click(object sender, ToolStripItemClickedEventArgs e)
        {
            switch (e.ClickedItem.Text)
            {
                case STR_RefreshList: //刷新列表
                    {                        
                        RefreshTreeView();
                    }
                    break;
                case STR_RefreshPart: //局部刷新
                case STR_RefreshSrt: //刷新字幕
                    {
                        RefreshTreeViewPart(treeView1.SelectedNode);
                    }
                    break;
                case STR_SearchUndownloadsForOneShow: //找到最新集
                    {
                        SearchForNewEpisodes();
                    }
                    break;
                //case STR_SearchUndownloadsForAllShow: //查找全部的最新集
                //    break;
                case STR_RenameVideoFile: //重命名视频文件
                    {
                        RenameVidelFile(false);
                    }
                    break;
                case STR_RenameVideoFile_Auto: //自動重命名视频文件
                    {
                        RenameVidelFile(true);
                    }
                    break;
                case STR_Mark: //标记视频文件
                    {
                        ShowXml.AddMark(xmldoc_Shows, (XmlNode)treeView1.SelectedNode.Parent.Tag, treeView1.SelectedNode.ToolTipText);
                        ShowXml.Save(xmldoc_Shows);
                        RefreshTreeViewPart(treeView1.SelectedNode.Parent);
                    }
                    break;
                case STR_Unmark: //标记视频文件
                    {
                        ShowXml.DelMark(xmldoc_Shows, (XmlNode)treeView1.SelectedNode.Parent.Tag, treeView1.SelectedNode.ToolTipText);
                        ShowXml.Save(xmldoc_Shows);
                        RefreshTreeViewPart(treeView1.SelectedNode.Parent);
                    }
                    break;
                case STR_Playback: //播放视频
                    {                        
                        FileInfo videoFile = (FileInfo)treeView1.SelectedNode.Tag;
                        if (File.Exists(videoFile.FullName))
                        {
                            System.Diagnostics.Process.Start(videoFile.FullName);
                        }
                        else
                        {
                            MessageBox.Show("文件不存在，请刷新列表", "打开文件失败!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    break;
                case STR_SearchSubtitles:  //获取字幕
                    {
                        GetEpisodeSubtitle();
                    }
                    break;
                case STR_FileDetails: //文件详情
                    {                        
                        FileInfo fileInfo = (FileInfo)treeView1.SelectedNode.Tag;
                        Form_FileDetails formFileDetails = new Form_FileDetails(fileInfo);
                        formFileDetails.ShowDialog();
                    }
                    break;
                case STR_RenameSubtitles: //字幕改名
                    {
                        RenameSubFiles();
                    }
                    break;
                case STR_OpenFolder: //打开文件所在文件夹
                    {
                        //获取文件信息
                        FileInfo fileInfo = (FileInfo)treeView1.SelectedNode.Tag;

                        //打开文件夹
                        if (Directory.Exists(fileInfo.Directory.FullName))
                        {
                            System.Diagnostics.Process.Start(fileInfo.Directory.FullName);
                        }
                        else
                        {
                            MessageBox.Show("文件夹不存在，请刷新列表", "打开文件夹失败!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    break;
                case STR_MoveSubFile: //字幕移动
                    {
                        MoveSubFilesTo(treeView1.SelectedNode);
                    }
                    break;
                default:
                    break;
            }
        }

        private void GetEpisodeSubtitle()
        {
            string searchUrl = STR_SearchSite;
            XmlNode root = (XmlNode)treeView1.SelectedNode.Parent.Parent.Tag;
            searchUrl += ShowXml.GetShowFullName(root, " ").Replace(' ', '+');

            searchUrl += string.Format("+s*{0}e*{1}/", treeView1.SelectedNode.Parent.Name, treeView1.SelectedNode.ToolTipText);

            webBrowser1.Stop();
            webBrowser1.ProgressChanged -= new WebBrowserProgressChangedEventHandler(webBrowser1_ProgressChanged);
            webBrowser1.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(GetSubtitleInfo);
            progressBar1.Visible = false;
            
            webBrowser1.Navigate(new Uri(searchUrl));
            webBrowser1.ProgressChanged += new WebBrowserProgressChangedEventHandler(webBrowser1_ProgressChanged);
            webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(GetSubtitleInfo);
        }

        private void GetSubtitleInfo(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            HtmlElement body = webBrowser1.Document.Body;
            //TreeNode tr_show = treeView1.SelectedNode;
            //int curretnNumber = Convert.ToInt32(tr_show.ToolTipText);
            //int lastNumber = curretnNumber;
            //XmlNode root = (XmlNode)treeView1.SelectedNode.Parent.Tag;
            //string season = treeView1.SelectedNode.Name;
            //string showName = ShowXml.GetShowFullName(root, " ");

            //完成后取消委托
            webBrowser1.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(GetSubtitleInfo);
            //停止页面读取
            webBrowser1.Stop();

            //清空结果表
            listBox1.Items.Clear();

            //查询页面,获取最新集
            bool searchDone = false;
            xmldoc_SubList = new XmlDocument();
            XmlElement subsNode = xmldoc_SubList.CreateElement("Subtitles");
            xmldoc_SubList.AppendChild(subsNode);
            foreach (HtmlElement a in body.GetElementsByTagName("div")) //查找主页面Body
            {
                foreach (HtmlElement b in a.GetElementsByTagName("div")) //查找含有"Resultsdive"的结果页Body
                {
                    if (b.Id == "resultsdiv") //找到包含搜索结果的Div
                    {
                        foreach (HtmlElement c in b.Children) //遍历所有结果
                        {
                            if (c.Children.Count > 2 && c.Children[2].Id == "sublist_ul") //只读取结果项
                            {
                                XmlElement subinfo = xmldoc_SubList.CreateElement("subtitle");
                                string url, type, language, producter, reviser, uploader, publisherName, /*publisherUrl,*/ uploadDate, viewCount, timelineBy, downloadCount;
                                url = c.FirstChild.FirstChild.GetAttribute("href");
                                foreach(HtmlElement d in c.Children[2].Children)
                                {
                                    try
                                    {
                                        switch (d.InnerText.Substring(0, 2))
                                        {
                                            case "格式":
                                                type = d.InnerText.Substring(3).Trim();
                                                subinfo.SetAttribute("格式", null,type);
                                                break;
                                            case "语言":
                                                language = d.InnerText.Substring(3).Trim();
                                                subinfo.SetAttribute("语言", null, language);
                                                break;
                                            case "制作":
                                                producter = d.InnerText.Substring(3).Trim();
                                                subinfo.SetAttribute("制作", null, producter);
                                                break;
                                            case "校订":
                                                reviser = d.InnerText.Substring(3).Trim();
                                                subinfo.SetAttribute("校订", null, reviser);
                                                break;
                                            case "上载":
                                                uploader = d.InnerText.Substring(3).Trim();
                                                subinfo.SetAttribute("上载", null, uploader);
                                                break;
                                            case "发行":
                                                publisherName = d.InnerText.Substring(3).Trim();
                                                subinfo.SetAttribute("发行", null, publisherName);
                                                break;
                                            case "查阅":
                                                viewCount = d.Children[0].InnerText.Replace("sub,", "").Trim();
                                                subinfo.SetAttribute("查阅", null, viewCount);
                                                break;
                                            case "日期":
                                                uploadDate = d.InnerText.Substring(3).Trim();
                                                subinfo.SetAttribute("日期", null, uploadDate);
                                                break;
                                            case "调校":
                                                timelineBy = d.InnerText.Substring(3).Trim();
                                                subinfo.SetAttribute("调校", null, timelineBy);
                                                break;
                                            case "下载":
                                                downloadCount = d.Children[0].InnerText.Replace("file,", "").Trim();
                                                subinfo.SetAttribute("下载", null, downloadCount);
                                                break;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        MessageBox.Show(ex.Message);
                                    }
                                }
                                subsNode.AppendChild(subinfo);
                            }
                            continue;
                        }
                        searchDone = true;
                        break;
                    }
                }
                if (searchDone)
                {
                    break;
                }
            }
        }

        
        /// <summary>
        /// 生成复制/移动文件所需的文件夹菜单
        /// </summary>
        /// <param name="move_or_copy">0: 移动; 1: 拷贝; 2:移动并保留共享</param>
        /// <param name="is_add_share_folder">是否包括共享文件夹</param>
        /// <returns></returns>
        private ToolStripMenuItem CreateFolderSelectMenu(int move_or_copy)
        {
            {   
                //生成空菜单
                ToolStripMenuItem tool_strip_folder = new ToolStripMenuItem();

                if (move_or_copy == 0)
                {
                    tool_strip_folder.Text = STR_VideoMoveTo;
                }
                else if (move_or_copy == 1)
                {
                    tool_strip_folder.Text = STR_VideoCopyTo;
                }
                else if (move_or_copy == 2)
                {
                    tool_strip_folder.Text = STR_VideoMoveToAndShare;
                }

                //选择“季”为根节点
                TreeNode root = null;
                if (treeView1.SelectedNode.Level == 1)
                {
                    root = treeView1.SelectedNode;
                }
                else if (treeView1.SelectedNode.Level == 2)
                {
                    root = treeView1.SelectedNode.Parent;
                }

                //遍历文件生成菜单
                foreach (TreeNode tn_show in root.Nodes)
                {
                    FileInfo file_info = (FileInfo)tn_show.Tag;
                    if (!tool_strip_folder.DropDownItems.ContainsKey(file_info.DirectoryName))
                    {
                        tool_strip_folder.DropDownItems.Add(file_info.DirectoryName);
                        tool_strip_folder.DropDownItems[tool_strip_folder.DropDownItems.Count - 1].Name = file_info.DirectoryName;
                    }
                }

                //如果所选节点是文件，则删除所选文件的文件夹
                if (treeView1.SelectedNode.Level == 2)
                {
                    string selected_node_folder_path = ((FileInfo)treeView1.SelectedNode.Tag).DirectoryName;
                    tool_strip_folder.DropDownItems.RemoveByKey(selected_node_folder_path);
                }

                tool_strip_folder.DropDownItems.Add("其他文件夹");

                if (move_or_copy == 0)
                {
                    tool_strip_folder.DropDownItemClicked -= CopyVideoFileTo;
                    tool_strip_folder.DropDownItemClicked -= MoveVideoFileTo;
                    tool_strip_folder.DropDownItemClicked -= CopyAndShareVideoFileTo;
                    tool_strip_folder.DropDownItemClicked += MoveVideoFileTo;
                }
                else if (move_or_copy == 1)
                {
                    tool_strip_folder.DropDownItemClicked -= CopyVideoFileTo;
                    tool_strip_folder.DropDownItemClicked -= MoveVideoFileTo;
                    tool_strip_folder.DropDownItemClicked -= CopyAndShareVideoFileTo;
                    tool_strip_folder.DropDownItemClicked += CopyVideoFileTo;
                }
                else if (move_or_copy == 2)
                {
                    tool_strip_folder.DropDownItemClicked -= CopyVideoFileTo;
                    tool_strip_folder.DropDownItemClicked -= MoveVideoFileTo;
                    tool_strip_folder.DropDownItemClicked -= CopyAndShareVideoFileTo;
                    tool_strip_folder.DropDownItemClicked += CopyAndShareVideoFileTo;
                }

                return tool_strip_folder;
            }
        }

        #endregion RightClick

        #region Functions

        #region copy and move

        /// <summary>
        /// 点击"复制到..."处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CopyVideoFileTo(object sender, ToolStripItemClickedEventArgs e)
        {
            string directory = e.ClickedItem.Text;
            List<FileInfo> file_info_list = new List<FileInfo>();
            //开始移动
            if (SetCopyOrMoveFileList(ref file_info_list, ref directory))
            {
                CopyOrMoveVideoFile(file_info_list, directory, 1);
            }
        }

        /// <summary>
        /// 点击"移动到..."处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MoveVideoFileTo(object sender, ToolStripItemClickedEventArgs e)
        {
            string directory = e.ClickedItem.Text;
            List<FileInfo> file_info_list = new List<FileInfo>();
            //开始移动
            if (SetCopyOrMoveFileList(ref file_info_list, ref directory))
            {
                CopyOrMoveVideoFile(file_info_list, directory, 0);
            }
        }

        /// <summary>
        /// 点击"移动并保留共享..."处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CopyAndShareVideoFileTo(object sender, ToolStripItemClickedEventArgs e)
        {
            string directory = e.ClickedItem.Text;
            List<FileInfo> file_info_list = new List<FileInfo>();
            //开始移动
            if (SetCopyOrMoveFileList(ref file_info_list, ref directory))
            {
                CopyOrMoveVideoFile(file_info_list, directory, 2);
            }
        }

        /// <summary>
        /// 生成复制或移动的文件列表及确定目标文件夹
        /// </summary>
        /// <param name="file_info_list">文件列表</param>
        /// <param name="directory">目标文件夹</param>
        /// <returns></returns>
        private bool SetCopyOrMoveFileList(ref  List<FileInfo> file_info_list, ref string directory)
        {
            //关闭右键菜单
            rightMouseButtonMenu.Close();

            //设置目标文件夹
            if (directory == "其他文件夹")
            {
                //弹出文件夹选择窗口
                if (folderBrowserDialog_MoveOrCopy.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    directory = folderBrowserDialog_MoveOrCopy.SelectedPath;
                }
                else
                {
                    //未选定目标文件夹，不复制或移动
                    return false;
                }
            }

            //设置文件列表
            FileInfo file_info = null;
            if (treeView1.SelectedNode.Level == 2)
            {
                //单一文件
                file_info = (FileInfo)treeView1.SelectedNode.Tag;
                if (file_info.Directory.FullName != directory)
                {
                    file_info_list.Add(file_info);
                }
            }
            else if (treeView1.SelectedNode.Level == 1)
            {
                //多个文件
                foreach (TreeNode tn_show in treeView1.SelectedNode.Nodes)
                {
                    file_info = (FileInfo)tn_show.Tag;
                    if (file_info.Directory.FullName != directory)
                    {
                        file_info_list.Add(file_info);
                    }
                }
            }

            if (file_info_list.Count == 0)
            {
                //无需要复制或移动的文件，返回失败
                //移动字幕文件
                MoveSubFilesTo(treeView1.SelectedNode);
                return false;
            }

            //返回成功
            return true;
        }

        /// <summary>
        /// 复制或移动视频文件
        /// </summary>
        /// <param name="file_info_list">文件信息列表</param>
        /// <param name="directory">目标目录</param>
        /// <param name="copy_or_move">0：移动 1：复制 2:移动并保留共享</param>
        private void CopyOrMoveVideoFile(List<FileInfo> file_info_list, string directory, int copy_or_move)
        {

            if (Directory.Exists(directory))
            {
                copy_or_move_file = new CopyOrMoveFile(file_info_list, directory, share_folder);

                listBox1.Items.Clear();
                treeView1.Enabled = false;
                button_Refresh.Enabled = false;

                //如果目标文件夹和现有文件都存在,则开始复制/拷贝
                Thread thread_copy_or_move = null;
                if (copy_or_move == 0)
                {
                    thread_copy_or_move = new Thread(new ThreadStart(copy_or_move_file.start_move));
                }
                else if (copy_or_move == 1)
                {
                    thread_copy_or_move = new Thread(new ThreadStart(copy_or_move_file.start_copy));
                }
                else if (copy_or_move == 2)
                {
                    thread_copy_or_move = new Thread(new ThreadStart(copy_or_move_file.start_move_and_share));
                }

                if (thread_copy_or_move != null)
                {
                    copy_or_move_file.OnCopyOrMoveFinish += new CopyOrMoveFile.CopyOrMoveFinish(CopyOrMoveEnd);
                    copy_or_move_file.OnCopyOrMoveAFileBegin += new CopyOrMoveFile.CopyOrMoveAFileBegin(CopyOrMoveFileBegin);

                    thread_copy_or_move.Start();
                }


            }
        }

        delegate void CopyOrMoveEndCallback(int move_or_copy);
        delegate void CopyOrMoveBeginCallback(FileInfo file_info, string directory, int copy_or_move);

        /// <summary>
        /// 当文件拷贝或移动完成
        /// </summary>
        /// <param name="move_or_copy">0:移动, 1:拷贝, 2:移动并保留共享</param>
        private void CopyOrMoveEnd(int move_or_copy)
        {
            //复制完成后刷新剧集树,更新文件信息
            if (listBox1.InvokeRequired || treeView1.InvokeRequired || button_Refresh.InvokeRequired)
            {
                CopyOrMoveEndCallback d = new CopyOrMoveEndCallback(CopyOrMoveEnd);
                this.Invoke(d, move_or_copy);
            }
            else
            {
                listBox1.Items.Clear();
                XmlNode xn_season = null;
                XmlNode xn_show = null;
                string season_number = "";
                if (treeView1.SelectedNode.Level == 2)
                {
                    //如果所选为视频
                    xn_season = (XmlNode)treeView1.SelectedNode.Parent.Tag;
                    xn_show = (XmlNode)treeView1.SelectedNode.Parent.Parent.Tag;
                    season_number = treeView1.SelectedNode.Parent.Name;
                }
                else
                {
                    //如果所选为季
                    xn_season = (XmlNode)treeView1.SelectedNode.Tag;
                    xn_show = (XmlNode)treeView1.SelectedNode.Parent.Tag;
                    season_number = treeView1.SelectedNode.Name;
                }

                List<FileSystemInfo> listVideoFiles = new List<FileSystemInfo>();
                List<FileSystemInfo> listSrtFiles = new List<FileSystemInfo>();

                GetSpecExtensionsFilesFromSpecFolders(Extensions_Video, ref listVideoFiles);
                GetSpecExtensionsFilesFromSpecFolders(Extensions_Srt, ref listSrtFiles);

                AppendEpisodeNode(season_number, xn_season, xn_show, ref listVideoFiles, ref listSrtFiles);

                //移动字幕文件
                MoveSubFilesTo(treeView1.SelectedNode);

                treeView1.Enabled = true;
                button_Refresh.Enabled = true;
            }
        }

        /// <summary>
        /// 当文件拷贝或移动开始，更新信息
        /// </summary>
        /// <param name="file_info">文件信息</param>
        /// <param name="directory">目标目录</param>
        /// <param name="copy_or_move">0：移动 1：复制 2:移动并保留共享</param>
        private void CopyOrMoveFileBegin(FileInfo file_info, string directory, int copy_or_move)
        {
            //复制完成后刷新剧集树,更新文件信息
            if (listBox1.InvokeRequired)
            {
                CopyOrMoveBeginCallback d = new CopyOrMoveBeginCallback(CopyOrMoveFileBegin);
                this.Invoke(d, file_info, directory, copy_or_move);
            }
            else
            {
                listBox1.Items.Clear();
                if (copy_or_move == 1)
                {
                    listBox1.Items.Add(string.Format("正在复制文件{0}到", file_info));
                }
                else
                {
                    listBox1.Items.Add(string.Format("正在移动文件{0}到", file_info));
                }
                listBox1.Items.Add(string.Format("{0}", directory));
            }
        }

        /// <summary>
        /// 移动字幕文件
        /// </summary>
        /// <param name="tn">所选中的字幕文件或视频文件节点</param>
        private void MoveSubFilesTo(TreeNode tn)
        {
            FileInfo videoFileInfo;
            List<FileInfo> subFilesInfo = new List<FileInfo>();
            //获取字幕文件信息和视频文件信息
            if (treeView1.SelectedNode.Level == 1)
            {
                //如果所选为季
                if (tn.Nodes.Count == 0)
                {
                    //无视频 直接返回
                    return;
                }
                videoFileInfo = (FileInfo)treeView1.SelectedNode.FirstNode.Tag;
                foreach (TreeNode tn_episodes in treeView1.SelectedNode.Nodes)
                {
                    foreach (TreeNode tn_sub in tn_episodes.Nodes)
                    {
                        subFilesInfo.Add((FileInfo)tn_sub.Tag);
                    }
                }
            }
            else if (tn.Level == 2)
            {
                //所选为视频文件
                videoFileInfo = (FileInfo)tn.Tag;
                foreach (TreeNode tn_sub in tn.Nodes)
                {
                    subFilesInfo.Add((FileInfo)tn_sub.Tag);
                }
            }
            else if (tn.Level == 3)
            {
                //所选为字幕文件
                videoFileInfo = (FileInfo)tn.Parent.Tag;
                subFilesInfo.Add((FileInfo)tn.Tag);
            }
            else
            {
                return;
            }

            //移动字幕文件到视频文件所在文件夹
            foreach (FileInfo subFile in subFilesInfo)
            {
                if (!Directory.Exists(videoFileInfo.Directory.FullName) || !File.Exists(subFile.FullName))
                {
                    MessageBox.Show("文件或文件夹不存在，请刷新列表", "移动字幕文件失败!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (subFile.Directory != videoFileInfo.Directory)
                {
                    try
                    {
                        subFile.MoveTo(string.Format("{0}\\{1}", videoFileInfo.Directory.FullName, subFile.Name));
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString(), "重命名失败!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        /// <summary>
        /// 文件拷贝或移动
        /// </summary>
        private class CopyOrMoveFile
        {
            private List<FileInfo> file_info_list;
            private string dest_folder;
            private string share_folder;
            private List<string> results = null;

            public delegate void CopyOrMoveFinish(int copy_or_move);
            public event CopyOrMoveFinish OnCopyOrMoveFinish;

            public delegate void CopyOrMoveAFileBegin(FileInfo file_info, string directory, int move_or_copy);
            public event CopyOrMoveAFileBegin OnCopyOrMoveAFileBegin;

            public CopyOrMoveFile(List<FileInfo> _file_info_list, string _dest_folder, string _share_folder)
            {
                results = null;
                file_info_list = _file_info_list;
                dest_folder = _dest_folder;
                share_folder = _share_folder;
            }

            public void start_copy()
            {
                results = null;
                //循环拷贝所有文件
                foreach (FileInfo file_info in file_info_list)
                {
                    //确定文件和目标文件夹存在
                    if (File.Exists(file_info.FullName) && Directory.Exists(dest_folder))
                    {
                        //开始复制
                        string new_file_fullname = string.Format("{0}\\{1}", dest_folder, file_info.Name);
                        try
                        {
                            OnCopyOrMoveAFileBegin(file_info, dest_folder, 0);
                            file_info.CopyTo(new_file_fullname);
                        }
                        catch (Exception ex)
                        {
                            results.Add(string.Format("Copy {0} to {1} failed: {2}", file_info.FullName, new_file_fullname, ex.Message));
                            continue;
                        }
                    }
                    else
                    {
                        //源文件或目标目录不存在
                        results.Add(string.Format("Copy {0} to {1} failed: {2}", file_info.FullName, dest_folder, "File or Directory no exist!"));
                    }
                }
                OnCopyOrMoveFinish(1);
                return;
            }

            public void start_move()
            {
                results = null;
                //循环移动所有文件
                foreach (FileInfo file_info in file_info_list)
                {
                    //开始移动
                    if (File.Exists(file_info.FullName) && Directory.Exists(dest_folder))
                    {
                        string new_file_fullname = string.Format("{0}\\{1}", dest_folder, file_info.Name);
                        try
                        {
                            OnCopyOrMoveAFileBegin(file_info, dest_folder, 1);
                            file_info.MoveTo(new_file_fullname);
                        }
                        catch (Exception ex)
                        {
                            results.Add(string.Format("Move {0} to {1} failed: {2}", file_info.FullName, new_file_fullname, ex.Message));
                            return;
                        }
                    }
                    else
                    {
                        //源文件或目标目录不存在
                        results.Add(string.Format("Move {0} to {1} failed: {2}", file_info.FullName, dest_folder, "File or Directory no exist!"));
                    }
                }
                OnCopyOrMoveFinish(0);
                return;
            }

            public void start_move_and_share()
            {
                results = null;
                //循环移动所有文件
                foreach (FileInfo file_info in file_info_list)
                {
                    //开始移动
                    if (File.Exists(file_info.FullName) && Directory.Exists(dest_folder) && Directory.Exists(share_folder))
                    {
                        string new_file_fullname ="";
                        try
                        {
                            OnCopyOrMoveAFileBegin(file_info, dest_folder, 1);
                            if (file_info.Directory.Root.ToString() == Directory.GetDirectoryRoot(share_folder))
                            {
                                new_file_fullname = string.Format("{0}\\{1}", dest_folder, file_info.Name);
                                file_info.CopyTo(new_file_fullname);
                                new_file_fullname = string.Format("{0}\\{1}", share_folder, file_info.Name);
                                file_info.MoveTo(new_file_fullname);
                            }
                            else
                            {
                                new_file_fullname = string.Format("{0}\\{1}", dest_folder, file_info.Name);
                                file_info.MoveTo(new_file_fullname);
                                new_file_fullname = string.Format("{0}\\{1}", share_folder, file_info.Name);
                                file_info.CopyTo(new_file_fullname);
                            }
                        }
                        catch (Exception ex)
                        {
                            results.Add(string.Format("Move {0} to {1} failed: {2}", file_info.FullName, new_file_fullname, ex.Message));
                            return;
                        }
                    }
                    else
                    {
                        //源文件或目标目录不存在
                        results.Add(string.Format("Move {0} to {1} failed: {2}", file_info.FullName, dest_folder, "File or Directory no exist!"));
                    }
                }
                OnCopyOrMoveFinish(2);
                return;
            }

            public List<string> GetResult()
            {
                return results;
            }
        }

        #endregion copy and move

        #region Common

        /// <summary>
        /// 读取Folder文件,获取文件夹信息
        /// </summary>
        private void ReadXml()
        {
            xmldoc_Folders = new XmlDocument();
            xmldoc_Folders.Load(NameStrings.FILENAME_FOLDER);
            XmlNode xn = xmldoc_Folders.SelectSingleNode(NameStrings.FLODERS).SelectSingleNode(NameStrings.SHAREFLODER);
            if (xn != null)
            {
                share_folder = xn.InnerText;
            }

            xmldoc_Shows = ShowXml.Read();
        }

        /// <summary>
        /// 获取文件集号
        /// </summary>
        /// <param name="strFilename">文件名</param>
        /// <param name="strSeason">第几季</param>
        /// <returns>第几集</returns>
        private string GetShowNumber(string strFilename, string strSeason)
        {
            string[] FileNamePartList = strFilename.ToLower().Split(splitChar);
            return GetShowNumber(FileNamePartList, strSeason);

        }

        /// <summary>
        /// 获取文件集号
        /// </summary>
        /// <param name="FileNamePartList">文件名拆分后字符串列表</param>
        /// <param name="strSeason">第几季</param>
        /// <returns>第几集</returns>
        private string GetShowNumber(string[] FileNamePartList, string strSeason)
        {
            string[] seasonStringList = {string.Format("s0{0}e", strSeason),
                                            string.Format("s{0}e", strSeason),
                                            string.Format("{0}x", strSeason),
                                            string.Format("{0}", strSeason)};

            string matchedString = null;
            //用特定字符串开头循环查找
            foreach (string seasonString in seasonStringList)
            {
                //对字符串中所有子串循环查找
                foreach (string nameString in FileNamePartList)
                {
                    //如果是子串符合指定开头
                    if (nameString.StartsWith(seasonString))
                    {
                        //matchedString = nameString.Replace(seasonString, "");
                        matchedString = nameString.Remove(0, seasonString.Length);

                        //如果子串去除开头后不为空
                        if (!string.IsNullOrEmpty(matchedString))
                        {
                            int number = 0;
                            //如果子串去除开头后长度不超过3且为一个数字
                            if (matchedString.Length <= 3 && int.TryParse(matchedString, out number))
                            {
                                //如果数字不大过50(一般美剧单季为24集)
                                if (number < 50)
                                {
                                    return matchedString;
                                }
                            }
                        }
                    }
                }
            }
            return "";
        }

        /// <summary>
        /// 根据剧集信息筛选文件
        /// </summary>
        /// <param name="listFiles">文件列表</param>
        /// <param name="xn_show">存储剧集信息的Xml节点</param>
        /// <returns>符合条件的文件列表</returns>
        private List<FileSystemInfo> SearchFiles(ref List<FileSystemInfo> listFiles, XmlNode xn_show, string season)
        {
            List<FileSystemInfo> selectedFiles = new List<FileSystemInfo>();
            int n = 0;

            //筛选文件
            foreach (FileSystemInfo file in listFiles)
            {
                if (IsNameMatch(file.Name, xn_show, season))
                {
                    selectedFiles.Add(file);
                }
                n++;
            }

            //将筛选出的文件从原列表移除
            foreach (FileSystemInfo file in selectedFiles)
            {
                listFiles.Remove(file);
            }

            return selectedFiles;
        }

        /// <summary>
        /// 根据文件名/字符串判断是否为指定剧集
        /// </summary>
        /// <param name="name">文件名/网页剧集信息字符串</param>
        /// <param name="xn_show">存储剧集信息的XML节点</param>
        /// <returns>文件名/字符串是否为指定剧集</returns>
        private bool IsNameMatch(string name, XmlNode xn_show, string season)
        {
            XmlNode xn_name = xn_show.SelectSingleNode(NameStrings.NAME);
            XmlNode xn_childnames = xn_show.SelectSingleNode(NameStrings.CHILDNAMES);

            string[] FileNamePartList = name.ToLower().Split(splitChar);

            //根据剧集名筛选
            foreach (XmlNode xn_namestring in xn_name.ChildNodes)
            {
                if (!FileNamePartList.Contains<string>(xn_namestring.Attributes[NameStrings.VALUE].Value))
                {
                    return false;
                }
            }

            //根据季号筛选
            //XmlNode xn_Season = xn_show.SelectSingleNode(NameStrings.SEASON);
            //season = xn_Season.Attributes[NameStrings.VALUE].Value;
            if (string.IsNullOrEmpty(GetShowNumber(FileNamePartList, season)))
            {
                return false;
            }

            //根据分剧集名筛选
            int matchcCount = 0;
            if (xn_childnames != null)
            {
                foreach (XmlNode xn_childname in xn_childnames.ChildNodes)
                {
                    bool isMatch = true;
                    foreach (XmlNode xn_childnamestr in xn_childname.ChildNodes)
                    {
                        if (!FileNamePartList.Contains<string>(xn_childnamestr.Attributes[NameStrings.VALUE].Value))
                        {
                            isMatch = false;
                            break;
                        }
                    }
                    if (isMatch == true)
                    {
                        matchcCount++;
                        break;
                    }
                }

                if (matchcCount <= 0)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            else
            {
                return true;
            }
        }


        /// <summary>
        /// 从所有文件夹中查找特定扩展名的文件
        /// </summary>
        /// <param name="extensions">指定扩展名</param>
        /// <param name="listFiles">返回的文件列表</param>
        private void GetSpecExtensionsFilesFromSpecFolders(string[] extensions, ref List<FileSystemInfo> listFiles)
        {
            foreach (XmlNode xn in xmldoc_Folders.SelectSingleNode(NameStrings.FLODERS).ChildNodes)
            {
                if (xn.Name == NameStrings.FLODER && Directory.Exists(xn.InnerText))
                {
                    DirectoryInfo dirInfo = new DirectoryInfo(xn.InnerText);
                    GetSpecExtensionsFilesFromFolder(dirInfo, extensions, ref listFiles);
                }
            }
        }

        /// <summary>
        /// 获取指定文件夹内指定扩展名的文件
        /// </summary>
        /// <param name="dirInfo">指定的文件夹</param>
        /// <param name="extensions">指定的扩展名</param>
        /// <param name="listFiles">返回的结果列表</param>
        private void GetSpecExtensionsFilesFromFolder(DirectoryInfo dirInfo, string[] extensions, ref List<FileSystemInfo> listFiles)
        {            
            foreach (string file in  Directory.GetFiles(dirInfo.FullName, "*", SearchOption.AllDirectories))
            {
                foreach (string extension in extensions)
                {
                    if (file.EndsWith(extension))
                    {
                        listFiles.Add(new FileInfo(file));
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// 选中字幕重命名
        /// </summary>
        private void RenameSubFiles()
        {
            FileInfo srtFile = (FileInfo)treeView1.SelectedNode.Tag;
            string[] srtFileStrings = srtFile.Name.ToLower().Split(new char[] { '.' });
            FileInfo videoFile = (FileInfo)treeView1.SelectedNode.Parent.Tag;
            string newName = videoFile.Name.Remove((int)videoFile.Name.Length - videoFile.Extension.Length);
            if (srtFileStrings[srtFileStrings.Length - 2] == "en" ||
                srtFileStrings[srtFileStrings.Length - 2] == "eng")
            {
                newName = string.Format("{0}\\{1}.{2}{3}", srtFile.DirectoryName, newName, srtFileStrings[srtFileStrings.Length - 2], srtFile.Extension);
            }
            else
            {
                newName = string.Format("{0}\\{1}{2}", srtFile.DirectoryName, newName, srtFile.Extension);
            }

            if (File.Exists(srtFile.FullName))
            {
                //重命名文件
                try
                {
                    srtFile.MoveTo(newName);
                    treeView1.SelectedNode.Tag = srtFile;
                    treeView1.SelectedNode.Name = srtFile.FullName;
                    treeView1.SelectedNode.Text = srtFile.Name;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "重命名失败!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("文件不存在，请刷新列表", "重命名失败!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 视频重命名
        /// </summary>
        /// <param name="isAuto">是否自動重命名</param>
        private void RenameVidelFile(bool isAuto)
        {
            FileInfo videoFile = (FileInfo)treeView1.SelectedNode.Tag;
            string OldName = videoFile.Name.Remove(videoFile.Name.Length - videoFile.Extension.Length);

            Form_Rename form_Rename = null;
            if (isAuto)
            {//自動生成新文件名

                //替換空格
                string newFileName = OldName.Replace(' ', '.');

                //替換集號
                int seasonNum = Convert.ToInt32(treeView1.SelectedNode.Parent.Name);
                int epNum = Convert.ToInt32(treeView1.SelectedNode.ToolTipText);
                string possibleEpNum_1 = string.Format(".{0:d}x{1:d2}.", seasonNum, epNum);
                string possibleEpNum_2 = string.Format(".{0:d}{1:d2}.", seasonNum, epNum);
                string possibleEpNum_3 = string.Format(".s{0:d}e{1:d2}.", seasonNum, epNum);
                string standardEpNum = string.Format(".S{0:d2}E{1:d2}.", seasonNum, epNum);
                if (newFileName.Contains(possibleEpNum_1))      
                {
                    newFileName = newFileName.Replace(possibleEpNum_1, standardEpNum);
                }
                else if (OldName.Contains(possibleEpNum_2))
                {
                    newFileName = newFileName.Replace(possibleEpNum_2, standardEpNum);
                }
                else if (OldName.Contains(possibleEpNum_3))
                {
                    newFileName = newFileName.Replace(possibleEpNum_3, standardEpNum);
                }

                //替换".[***]"内容
                int bracketStart = newFileName.IndexOf(".[");
                int bracketEnd = newFileName.IndexOf(']');
                while (bracketStart > 0 && bracketEnd > 0)
                {
                    newFileName = newFileName.Remove(bracketStart, bracketEnd - bracketStart + 1);

                    if (bracketStart < newFileName.Length - 1)
                    {
                        int startPoint = bracketStart;
                        bracketStart = newFileName.IndexOf(".[", startPoint);
                        bracketEnd = newFileName.IndexOf(']', startPoint);
                    }
                    else
                    {
                        break;
                    }
                }

                //替换".(***)"内容
                bracketStart = newFileName.IndexOf(".(");
                bracketEnd = newFileName.IndexOf(')');
                while (bracketStart > 0 && bracketEnd > 0)
                {
                    newFileName = newFileName.Remove(bracketStart, bracketEnd - bracketStart + 1);

                    if (bracketStart < newFileName.Length - 1)
                    {
                        int startPoint = bracketStart;
                        bracketStart = newFileName.IndexOf(".(", startPoint);
                        bracketEnd = newFileName.IndexOf(')', startPoint);
                    }
                    else
                    {
                        break;
                    }
                }


                form_Rename = new Form_Rename(OldName, newFileName);
            }
            else
            {
                form_Rename = new Form_Rename(OldName);
            }

            if (form_Rename.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string newName = string.Format("{0}\\{1}{2}", videoFile.DirectoryName, form_Rename.NewFileName, videoFile.Extension);

                //重命名文件
                if (File.Exists(videoFile.FullName))
                {
                    try
                    {
                        videoFile.MoveTo(newName);
                        treeView1.SelectedNode.Tag = videoFile;
                        treeView1.SelectedNode.Name = videoFile.FullName;
                        treeView1.SelectedNode.Text = videoFile.Name;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString(), "重命名失败!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("文件不存在，请刷新列表", "重命名失败!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }  
        }

        #endregion Common

        #region Tree

        /// <summary>
        /// 刷新整个树列表
        /// </summary>
        private void RefreshTreeView()
        {
            //查看必要配置文件是否存在
            if (!File.Exists(NameStrings.FILENAME_SHOW) || !File.Exists(NameStrings.FILENAME_FOLDER))
            {
                MessageBox.Show("请先设置剧集和文件夹", "读取错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                //不存在则引导用户设置
                if (!File.Exists(NameStrings.FILENAME_SHOW))
                {
                    ShowManage form_ShowManage = new ShowManage();
                    form_ShowManage.ShowDialog();
                } 
                if (!File.Exists(NameStrings.FILENAME_FOLDER))
                {
                    FolderManage form_ShowManage = new FolderManage();
                    form_ShowManage.ShowDialog();
                }

                //如果引导后用户仍未作设置,则直接返回,如果已设置则进入正常刷新流程
                if (!File.Exists(NameStrings.FILENAME_SHOW) || !File.Exists(NameStrings.FILENAME_FOLDER))
                {
                    return;
                }
            }

            //从文件读取所有剧集,文件夹信息
            ReadXml();

            //如果树为空或者树信息与文件信息不相符,则清空树
            if (treeView1.Tag == null || !treeView1.Tag.Equals(xmldoc_Shows.InnerXml))
            {
                treeView1.Tag = xmldoc_Shows.InnerXml;
                treeView1.Nodes.Clear();
            }

            //获取文件夹所有视频字幕文件
            List<FileSystemInfo> listVideoFiles = new List<FileSystemInfo>();
            List<FileSystemInfo> listSrtFiles = new List<FileSystemInfo>();
            GetSpecExtensionsFilesFromSpecFolders(Extensions_Video, ref listVideoFiles);
            GetSpecExtensionsFilesFromSpecFolders(Extensions_Srt, ref listSrtFiles);

            foreach (XmlNode xn in xmldoc_Shows.SelectSingleNode(NameStrings.SHOWS).ChildNodes)
            {
                AppendShowSeasonNode(xn, ref listVideoFiles, ref listSrtFiles);
            }
        }
        /// <summary>
        /// 刷新列表
        /// </summary>
        /// <param name="tn">指定节点</param>
        private void RefreshTreeViewPart(TreeNode tn)
        {
            if (tn.Level == 0)
            {
                //所选为剧集
                XmlNode xn_show = (XmlNode)tn.Tag;

                List<FileSystemInfo> listVideoFiles = new List<FileSystemInfo>();
                List<FileSystemInfo> listSrtFiles = new List<FileSystemInfo>();

                GetSpecExtensionsFilesFromSpecFolders(Extensions_Video, ref listVideoFiles);
                GetSpecExtensionsFilesFromSpecFolders(Extensions_Srt, ref listSrtFiles);

                AppendShowSeasonNode(xn_show, ref listVideoFiles, ref listSrtFiles);
            }
            else if (tn.Level == 1)
            {
                //所选为季
                XmlNode xn_show = (XmlNode)tn.Parent.Tag;
                XmlNode xn_season = (XmlNode)tn.Tag;

                List<FileSystemInfo> listVideoFiles = new List<FileSystemInfo>();
                List<FileSystemInfo> listSrtFiles = new List<FileSystemInfo>();

                GetSpecExtensionsFilesFromSpecFolders(Extensions_Video, ref listVideoFiles);
                GetSpecExtensionsFilesFromSpecFolders(Extensions_Srt, ref listSrtFiles);

                //按季挂树
                AppendEpisodeNode(tn.Name, xn_season, xn_show, ref listVideoFiles, ref listSrtFiles);
            }
            else if (tn.Level == 2)
            {
                //所选为剧集
                XmlNode xn_show = (XmlNode)tn.Parent.Parent.Tag;
                string season = tn.Parent.Name;

                List<FileSystemInfo> listSrtFiles = new List<FileSystemInfo>();
                GetSpecExtensionsFilesFromSpecFolders(Extensions_Srt, ref listSrtFiles);

                List<FileSystemInfo> listSelectedSrtFiles = SearchFiles(ref listSrtFiles, xn_show, season);
                //字幕挂树
                AppendSrtToVideo(tn, listSelectedSrtFiles, season);
            }
        }

        /// <summary>
        /// 根据制定剧集节点将视频文件挂树
        /// </summary>
        /// <param name="xn_show">储存剧集信息的节点</param>
        /// <param name="listVideoFiles">视频文件列表</param>
        /// <param name="listSrtFiles">字幕文件列表</param>
        private void AppendShowSeasonNode(XmlNode xn_show, ref List<FileSystemInfo> listVideoFiles, ref List<FileSystemInfo> listSrtFiles)
        {
            //非空剧集挂树
            if (xn_show.SelectNodes(NameStrings.SEASON).Count > 0)
            {
                string strShowName = ShowXml.GetShowFullName(xn_show, ": ");
                //不存在本剧或者本剧信息与现在信息不符
                if (!treeView1.Nodes.ContainsKey(strShowName) || treeView1.Nodes[strShowName].Tag != xn_show)
                {
                    if (!treeView1.Nodes.ContainsKey(strShowName))
                    {
                        //不存在本剧，添加
                        treeView1.Nodes.Add(strShowName, strShowName);
                    }
                    else if (treeView1.Nodes[strShowName].Tag != xn_show)
                    {
                        //存在但信息不符,清楚信息
                        treeView1.Nodes[strShowName].Nodes.Clear();
                    }

                    //重写信息
                    treeView1.Nodes[strShowName].Tag = xn_show;

                    //按季挂树
                    foreach (XmlNode xn_season in xn_show.SelectNodes(NameStrings.SEASON))
                    {
                        string season = xn_season.Attributes[NameStrings.VALUE].Value;
                        AppendEpisodeNode(season, xn_season, xn_show, ref listVideoFiles, ref listSrtFiles);
                    }
                }
            }
        }

        /// <summary>
        /// 将文件挂在"季"节点上
        /// </summary>
        /// <param name="season">第几季</param>
        /// <param name="xn_season">季XML节点</param>
        /// <param name="xn_show">剧集XML节点</param>
        /// <param name="listSelectedVideoFiles">根据剧集筛选的视频文件列表</param>
        /// <param name="listSelectedSrtFiles">根据剧集筛选的字幕文件列表</param>
        private void AppendEpisodeNode(string season, XmlNode xn_season, XmlNode xn_show, ref List<FileSystemInfo> listVideoFiles, ref List<FileSystemInfo> listSrtFiles)
        {
            string strShowName = ShowXml.GetShowFullName(xn_show, ": ");

            //获取视频和字幕文件
            List<FileSystemInfo> listSelectedVideoFiles = SearchFiles(ref listVideoFiles, xn_show, season);
            List<FileSystemInfo> listSelectedSrtFiles = SearchFiles(ref listSrtFiles, xn_show, season);

            //按季挂树
            if (!treeView1.Nodes[strShowName].Nodes.ContainsKey(season))
            {
                treeView1.Nodes[strShowName].Nodes.Add(season, string.Format("Season{0}", season));
            }
            treeView1.Nodes[strShowName].Nodes[season].Tag = xn_season;
            treeView1.Nodes[strShowName].Nodes[season].ToolTipText = "0";

            List<string> marked_list = new List<string>();

            foreach(XmlNode xn_mark in xn_season.SelectNodes(NameStrings.MARK))
            {
                string mark = xn_mark.Attributes[NameStrings.VALUE].Value;
                marked_list.Add(mark);
            }


            //移除视频文件列表中已挂树的文件
            for (int i = treeView1.Nodes[strShowName].Nodes[season].Nodes.Count - 1; i >= 0; i--)
            {
                TreeNode tn_episode = treeView1.Nodes[strShowName].Nodes[season].Nodes[i];
                bool getMatch = false;                
                string strNumber = tn_episode.ToolTipText;
                foreach (FileSystemInfo file in listSelectedVideoFiles)
                {
                    if (file.FullName == tn_episode.Name)
                    {
                        listSelectedVideoFiles.Remove(file);
                        tn_episode.Tag = file;
                        if (Convert.ToInt32(strNumber) > Convert.ToInt32(treeView1.Nodes[strShowName].Nodes[season].ToolTipText))
                        {
                            treeView1.Nodes[strShowName].Nodes[season].ToolTipText = strNumber;
                        }
                        getMatch = true;
                        break;
                    }
                }
                if (!getMatch)
                {
                    tn_episode.Remove();
                }
            }

            //将选出的视频文件挂树
            foreach (FileSystemInfo file in listSelectedVideoFiles)
            {
                //获取剧集集号
                string strNumber = GetShowNumber(file.Name, season);

                if (string.IsNullOrEmpty(strNumber))
                {
                    continue;
                }

                //视频文件挂树
                if (Convert.ToInt32(strNumber) >= Convert.ToInt32(treeView1.Nodes[strShowName].Nodes[season].ToolTipText))
                {
                    treeView1.Nodes[strShowName].Nodes[season].Nodes.Add(file.FullName, file.Name);
                    treeView1.Nodes[strShowName].Nodes[season].ToolTipText = strNumber;
                }
                else
                {
                    foreach (TreeNode tn in treeView1.Nodes[strShowName].Nodes[season].Nodes)
                    {
                        if (Convert.ToInt32(strNumber) < Convert.ToInt32(tn.ToolTipText))
                        {
                            treeView1.Nodes[strShowName].Nodes[season].Nodes.Insert(tn.Index, file.FullName, file.Name);
                            break;
                        }
                    }
                }
                treeView1.Nodes[strShowName].Nodes[season].Nodes[file.FullName].Tag = file;
                treeView1.Nodes[strShowName].Nodes[season].Nodes[file.FullName].ToolTipText = strNumber;
            }
            
            //根据标记列表检查并标记视频
            foreach (TreeNode tn_episode in treeView1.Nodes[strShowName].Nodes[season].Nodes)
            {
                CheckMark(marked_list, tn_episode);
                AppendSrtToVideo(tn_episode, listSelectedSrtFiles, season);
            }
            
        }

        /// <summary>
        /// 刷新指定集的字幕
        /// </summary>
        /// <param name="tn_episode">指定视频的树节点</param>
        /// <param name="listSelectedSrtFiles">所有字幕文件列表</param>
        /// <param name="season">季号</param>
        private void AppendSrtToVideo(TreeNode tn_episode, List<FileSystemInfo> listSelectedSrtFiles, string season)
        {
            //清除字幕列表
            tn_episode.Nodes.Clear();

            //字幕文件挂树
            string strNumber = tn_episode.ToolTipText;
            foreach (FileSystemInfo srtFile in listSelectedSrtFiles)
            {
                if (strNumber == GetShowNumber(srtFile.Name, season))
                {
                    tn_episode.Nodes.Add(srtFile.FullName, srtFile.Name);
                    tn_episode.Nodes[srtFile.FullName].Tag = srtFile;
                }
            }
        }

        /// <summary>
        /// 根据标记列表标记视频节点
        /// </summary>
        /// <param name="marked_list">标记列表</param>
        /// <param name="tn_episode">视频节点</param>
        private void CheckMark(List<string> marked_list, TreeNode tn_episode)
        {
            if (marked_list.Contains(tn_episode.ToolTipText))
            {
                tn_episode.ForeColor = Color.Red;
            }
            else
            {
                tn_episode.ForeColor = Color.Black;
            }
        }
        
        #endregion Tree

        #region Search for new
        /// <summary>
        /// 开始查找最新集
        /// </summary>
        private void SearchForNewEpisodes()
        {
            string searchUrl = STR_SearchSite;
            XmlNode root = (XmlNode)treeView1.SelectedNode.Parent.Tag;
            XmlNode xn_name = root.SelectSingleNode(NameStrings.NAME);
            XmlNode xn_childnames = root.SelectSingleNode(NameStrings.CHILDNAMES);
            string season = treeView1.SelectedNode.Name;

            searchUrl += ShowXml.GetShowFullName(root, " ").Replace(' ', '+');

            searchUrl += string.Format("+s*{0}/", season);

            webBrowser1.Stop();
            webBrowser1.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(GetNotDownload);
            webBrowser1.ProgressChanged -= new WebBrowserProgressChangedEventHandler(webBrowser1_ProgressChanged);
            progressBar1.Visible = false;

            webBrowser1.Navigate(new Uri(searchUrl));

            listBox1.Items.Clear();
            listBox1.Items.Add("开始网页查询...");
            treeView1.Enabled = false;
            button_Refresh.Enabled = false;
            webBrowser1.ProgressChanged += new WebBrowserProgressChangedEventHandler(webBrowser1_ProgressChanged);
            webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(GetNotDownload);
        }
        
        /// <summary>
        /// 页面读取完成后，查找未下载集
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GetNotDownload(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            HtmlElement body = webBrowser1.Document.Body;
            TreeNode tr_show = treeView1.SelectedNode;
            int curretnNumber = Convert.ToInt32(tr_show.ToolTipText);
            int lastNumber = curretnNumber;
            XmlNode root = (XmlNode)treeView1.SelectedNode.Parent.Tag;
            string season = treeView1.SelectedNode.Name;
            string showName = ShowXml.GetShowFullName(root, " ");
            //完成后取消委托
            webBrowser1.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(GetNotDownload);
            //停止页面读取
            webBrowser1.Stop();

            //清空结果表
            listBox1.Items.Clear();

            //查询页面,获取最新集
            foreach (HtmlElement a in body.GetElementsByTagName("div"))
            {
                foreach (HtmlElement b in a.GetElementsByTagName("div"))
                {
                    if (b.Id == "resultsdiv")
                    {
                        foreach (HtmlElement c in b.Children)
                        {
                            if (c.Children.Count > 2 && c.Children[2].Id == "sublist_ul")
                            {
                                if (IsNameMatch(c.Children[1].InnerText, root, season))
                                {
                                    string strNum = GetShowNumber(c.Children[1].InnerText, season);
                                    if (strNum == "")
                                    {
                                        continue;
                                    }
                                    int number = Convert.ToInt32(strNum);
                                    if (number > lastNumber)
                                    {
                                        lastNumber = number;
                                    }
                                }
                            }
                            continue;
                        }
                        break;
                    }
                }
            }

            for (int i = 1, treeIndex = 0; i <= lastNumber; i++)
            {
                if (tr_show.Nodes.Count > 0)
                {
                    if (treeIndex == tr_show.Nodes.Count)
                    {
                        listBox1.Items.Add(string.Format("{0} s{1:d2}e{2:d2}", showName, Convert.ToInt32(season), i));
                    }
                    else
                    {
                        while (treeIndex < tr_show.Nodes.Count && Convert.ToInt32(tr_show.Nodes[treeIndex].ToolTipText) < i)
                        {
                            treeIndex++;
                        }

                        if (treeIndex == tr_show.Nodes.Count || Convert.ToInt32(tr_show.Nodes[treeIndex].ToolTipText) != i)
                        {
                            listBox1.Items.Add(string.Format("{0} s{1:d2}e{2:d2}", showName, Convert.ToInt32(season), i));
                        }
                    }
                }
                else
                {
                    listBox1.Items.Add(string.Format("{0} s{1:d2}e{2:d2}", showName, Convert.ToInt32(season), i));
                }
            }

            if (listBox1.Items.Count == 0)
            {
                listBox1.Items.Add(string.Format("无结果返回：最新为s{0:d2}e{1:d2}", Convert.ToInt32(season), lastNumber));
            }

            treeView1.Enabled = true;
            button_Refresh.Enabled = true;
            progressBar1.Visible = false;
            ThreadObj.Set();
            return;
        }

        /// <summary>
        /// 重置浏览器
        /// </summary>
        private void BrowserReset()
        {
            webBrowser1.Stop();

            webBrowser1.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(BrowserResetFinished);
            webBrowser1.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(GetSubtitleInfo);
            webBrowser1.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(GetNotDownload);
            webBrowser1.ProgressChanged -= new WebBrowserProgressChangedEventHandler(webBrowser1_ProgressChanged);
            progressBar1.Visible = false;

            webBrowser1.Navigate(new Uri("about:blank"));
            treeView1.Enabled = true;
            button_Refresh.Enabled = true;

            //webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(BrowserResetFinished);
        }
        
        /// <summary>
        /// 页面读取完成后，查找未下载集
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BrowserResetFinished(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            webBrowser1.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(BrowserResetFinished);
        }

        //网页进度条
        private void webBrowser1_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e)
        {
            progressBar1.Visible = true;
            if ((e.CurrentProgress > 0) && (e.MaximumProgress > 0))
            {
                progressBar1.Maximum = Convert.ToInt32(e.MaximumProgress);//设置正在加载的文档总字节数
                progressBar1.Step = Convert.ToInt32(e.CurrentProgress);////获取已下载文档的字节数
                progressBar1.PerformStep();
            }
            else if (webBrowser1.ReadyState == WebBrowserReadyState.Complete)//加载完成后隐藏进度条
            {
                progressBar1.Value = 0;
                progressBar1.Visible = false;
            }
        }

        #endregion Search for new

        private void button1_Click(object sender, EventArgs e)
        {
            if (xmldoc_SubList.ChildNodes.Count == 0 || xmldoc_SubList.FirstChild.ChildNodes.Count == 0)
            {
                //无子节点，报错
            }
            else
            {

            }
        }

        #endregion Functions


    }
}
